<!DOCTYPE html>
<html>

<head>
    <title>Reinstall Logs</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            overflow: hidden;
        }

        #log-container {
            height: calc(100vh);
            margin: 0;
            padding: 8px;
            overflow-y: scroll;
        }

        #scroll-to-bottom {
            position: fixed;
            bottom: 24px;
            right: 24px;
            background-color: #0099FF;
            color: #fff;
            border: none;
            cursor: pointer;
            display: none;
            width: 48px;
            height: 48px;
            border-radius: 50%;
        }

        #scroll-to-bottom:hover {
            background-color: #00CCFF;
        }

        #scroll-to-bottom svg {
            fill: #fff;
        }

        .done {
            background-color: #cfc;
        }

        .error {
            background-color: #fcc;
        }
    </style>
</head>

<body>
    <pre id="log-container"></pre>
    <button id="scroll-to-bottom">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
            <path d="M5 10l7 7 7-7H5z" />
        </svg>
    </button>

    <script
        src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-d/reconnecting-websocket/1.0.0/reconnecting-websocket.min.js"
        type="application/javascript"></script>

    <script>
        const logContainer = document.getElementById('log-container');
        const scrollToBottomButton = document.getElementById('scroll-to-bottom');
        let shouldScrollToBottom = true;

        scrollToBottomButton.addEventListener('click', () => {
            logContainer.scrollTop = logContainer.scrollHeight;
        });

        logContainer.addEventListener('scroll', () => {
            const isAtBottom = Math.ceil(logContainer.scrollTop + logContainer.clientHeight) >= logContainer.scrollHeight;
            if (isAtBottom) {
                scrollToBottomButton.style.display = 'none';
            } else {
                scrollToBottomButton.style.display = 'block';
            }

            shouldScrollToBottom = isAtBottom;
        });

        var ws = new ReconnectingWebSocket('ws://' + location.host + '/');
        ws.onopen = function () {
            logContainer.textContent += '\nWebSocket Connected.';
        };
        ws.onclose = function () {
            logContainer.textContent += '\nWebSocket Disconnected.';
        };
        ws.onmessage = function (event) {
            logContainer.textContent += '\n' + event.data;
            if (shouldScrollToBottom) {
                logContainer.scrollTop = logContainer.scrollHeight;
            }
            // 开始/重新开始
            if (event.data.includes('***** START TRANS *****')) {
                document.body.className = ''
            }
            // 错误
            else if (event.data.includes('***** ERROR *****')) {
                document.body.className = 'error'
            }
            // 完成
            else if (event.data.includes('***** DONE *****')) {
                document.body.className = 'done'
            }
        };
    </script>
</body>

</html>
